//package objectRank;
//
///**
// *
// * @author Reza Amini
// */
//import java.io.Serializable;
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.Comparator;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.LinkedHashMap;
//import java.util.LinkedList;
//
//import edu.fiu.cis.personalize.server.graph.Document;
//import edu.fiu.cis.personalize.server.graph.Group;
//import edu.fiu.cis.personalize.server.graph.Node;
//import edu.fiu.cis.personalize.server.graph.NodeType;
//import edu.fiu.cis.personalize.server.graph.User;
//import edu.fiu.cis.personalize.shared.GoogleDocument;
//
//public class QueryGraph implements Serializable {
//	// The total number of nodes in the graph
//
//	// Damping factor
//	private final double d = 0.85;
//	private final double impFac = 0.5;
//	/*
//	 * Maps storing relationships from users, groups, queries, and documents to
//	 * numeric Identifyers
//	 */
//	// private HashMap<Node, Integer> nodeToIdentifyer;
//
//	private HashSet<Node> rootSet;
//	private HashSet<Node> baseSet;
//
//	// Constructor for WebGraph
//	public QueryGraph() {
//		// this.nodeToIdentifyer = new HashMap<Node, Integer>();
//
//		this.rootSet = new HashSet<Node>();
//		this.baseSet = new HashSet<Node>();
//	}
//
//	/**
//	 * Calculates the OutDegree of a specific type for a User node
//	 * 
//	 * @param user
//	 *            The user node which we want the OutDegree of
//	 * @param edgeType
//	 *            The type of out going edges
//	 * @return The OutDegree of the node
//	 */
//	private int outDegree(Node node, NodeType nodeType) {
//		return node.getOutDegree(nodeType);
//
//	}
//
//	// WTF is this code supposed to do
//
//	public HashMap<Node, Double> calculateObjectRank() {
//		// int baseSetCount = baseSet.size();
//		HashMap<Node, Double> currentRank = new HashMap<Node, Double>();
//		HashMap<Node, Double> resultRank = new HashMap<Node, Double>();
//		double difference = 0;
//		Node tempNode = null;
//		Iterator<Node> iter = nodeToIdentifyer.keySet().iterator();
//		while (iter.hasNext()) {
//			tempNode = iter.next();
//			currentRank.put(tempNode, 1.0 / nodeCount);
//			resultRank.put(tempNode, (1.0 - d) / nodeCount);
//			difference = +Math.pow(
//					currentRank.get(tempNode) - resultRank.get(tempNode), 2);
//		}
//		double threshold = Math.sqrt(difference);
//		double rank = 0;
//		Node x = null;
//		while (threshold > 0.001) {
//			iter = nodeToIdentifyer.keySet().iterator();
//			while (iter.hasNext()) {
//				rank = 0;
//				x = iter.next();
//				if ((x.getClass() != User.class)
//						&& !((x.inLinksFromUsers).isEmpty())) {
//					Iterator<Integer> userIter = x.inLinksFromUsers.keySet()
//							.iterator();
//					int e = 0;
//					while (userIter.hasNext()) {
//						Integer userId = userIter.next();
//						Node y = (Node) identifyerToUser(userId);
//						e = (baseSet.contains(y)) ? 1 : 0;
//						if (x.inLinksFromUsers.containsKey(userId)) {
//							double w = x.inLinksFromUsers.get(userId);
//							rank = +(w * alfa(y, x) * currentRank.get(y));
//						}
//					}
//					rank = rank * d + (1 - d) * e;
//				}
//
//				if ((x.getClass() != Document.class)
//						&& !((x.inLinksFromGroups).isEmpty())) {
//					Iterator<Integer> groupIter = x.inLinksFromGroups.keySet()
//							.iterator();
//					int e = 0;
//					while (groupIter.hasNext()) {
//						Integer groupId = groupIter.next();
//						Node y = (Node) identifyerToGroup(groupId);
//						e = (baseSet.contains(y)) ? 1 : 0;
//						if (x.inLinksFromGroups.containsKey(groupId)) {
//							double w = x.inLinksFromGroups.get(groupId);
//							rank = +(w * alfa(y, x) * currentRank.get(y));
//						}
//					}
//					rank = rank * d + (1 - d) * e;
//				}
//
//				if (!((x.inLinksFromQueries).isEmpty())) {
//					Iterator<Integer> queryIter = x.inLinksFromQueries.keySet()
//							.iterator();
//					int e = 0;
//					while (queryIter.hasNext()) {
//						Integer queryId = queryIter.next();
//						Node y = (Node) identifyerToQuery(queryId);
//						e = (baseSet.contains(y)) ? 1 : 0;
//						if (x.inLinksFromQueries.containsKey(queryId)) {
//							double w = x.inLinksFromQueries.get(queryId);
//							rank = +(w * alfa(y, x) * currentRank.get(y));
//						}
//					}
//					rank = rank * d + (1 - d) * e;
//				}
//
//				if ((x.getClass() != Group.class)
//						&& (x.getClass() != Document.class)
//						&& !((x.inLinksFromDocuments).isEmpty())) {
//					Iterator<Integer> documentIter = x.inLinksFromDocuments
//							.keySet().iterator();
//					int e = 0;
//					while (documentIter.hasNext()) {
//						Integer documentId = documentIter.next();
//						Node y = (Node) identifyerToDocument(documentId);
//						e = (baseSet.contains(y)) ? 1 : 0;
//						if (x.inLinksFromDocuments.containsKey(documentId)) {
//							double w = x.inLinksFromDocuments.get(documentId);
//							/*
//							 * System.out.println(w + "," +
//							 * authorityTransferRate(y, x) + "," + outDegree(y,
//							 * x) + "," + currentRank.get(y) + "," + e);
//							 */
//							rank = +(w * alfa(y, x) * currentRank.get(y));
//						}
//					}
//					rank = rank * d + (1 - d) * e;
//				}
//				resultRank.put(x, rank);
//			}
//			iter = nodeToIdentifyer.keySet().iterator();
//			difference = 0;
//			while (iter.hasNext()) {
//				tempNode = iter.next();
//				difference = +Math
//						.pow(currentRank.get(tempNode)
//								- resultRank.get(tempNode), 2);
//			}
//			threshold = Math.sqrt(difference);
//			currentRank = resultRank;
//		}
//		return resultRank;
//	}
//
//	public static LinkedHashMap<Node, Double> sortHashMapByValues(
//			final HashMap<Node, Double> passedMap) {
//		ArrayList<Node> l = new ArrayList<Node>(passedMap.keySet());
//		Collections.sort(l, new Comparator<Node>() {
//
//			@Override
//			public int compare(Node o1, Node o2) {
//				return passedMap.get(o1).compareTo(passedMap.get(o2));
//			}
//		});
//
//		LinkedHashMap<Node, Double> m = new LinkedHashMap<Node, Double>();
//		for (Node n : l) {
//			m.put(n, passedMap.get(n));
//		}
//		return m;
//	}
//
//	/**
//	 * 
//	 * @param objectRanks
//	 * @param googleOutput
//	 * @return
//	 */
//	public LinkedHashMap<GoogleDocument, Double> integrateWithGoogle(
//			HashMap<Node, Double> objectRanks,
//			LinkedList<GoogleDocument> googleOutput) {
//		Iterator<Node> nodeItr = objectRanks.keySet().iterator();
//		HashMap<Node, Double> tempObjRanks = new HashMap<Node, Double>();
//		while (nodeItr.hasNext()) {
//			Node nextNode = nodeItr.next();
//			if (nextNode.getClass() == Document.class) {
//				tempObjRanks.put(nextNode, objectRanks.get(nextNode));
//			}
//		}
//		LinkedHashMap<Node, Double> rankedNodes = sortHashMapByValues(tempObjRanks);
//		nodeItr = rankedNodes.keySet().iterator();
//		LinkedHashMap<Document, Double> documentRanks = new LinkedHashMap<Document, Double>();
//		while (nodeItr.hasNext()) {
//			Node tempNode = nodeItr.next();
//			Document doc = ((Document) tempNode);
//			documentRanks.put(doc, rankedNodes.get(tempNode));
//		}
//
//		double s1 = Collections.min(documentRanks.values());
//		double sn = Collections.max(documentRanks.values());
//		int n = documentRanks.size();
//		double step = (s1 + sn) / n;
//
//		Iterator<GoogleDocument> itr = googleOutput.iterator();
//		LinkedHashMap<GoogleDocument, Double> googleScoredOutput = new LinkedHashMap<GoogleDocument, Double>();
//		for (int i = 0; i < googleOutput.size(); i++) {
//			googleScoredOutput.put(itr.next(), step * (i + 1));
//		}
//
//		LinkedHashMap<GoogleDocument, Double> finalOutput = new LinkedHashMap<GoogleDocument, Double>();
//		Iterator<GoogleDocument> itr1 = googleScoredOutput.keySet().iterator();
//		GoogleDocument doc;
//		Iterator<Document> itr2;
//		while (itr1.hasNext()) {
//			doc = itr1.next();
//			String url = doc.getURL();
//			itr2 = documentRanks.keySet().iterator();
//			Document dd;
//			finalOutput.put(doc, (1 - impFac) * googleScoredOutput.get(doc));
//			while (itr2.hasNext()) {
//				dd = itr2.next();
//				if (dd.getURL().equalsIgnoreCase(url)) {
//					finalOutput.put(doc, impFac * documentRanks.get(dd)
//							+ (1 - impFac) * googleScoredOutput.get(doc));
//					break;
//				}
//			}
//		}
//		itr2 = documentRanks.keySet().iterator();
//		Document dd;
//		while (itr2.hasNext()) {
//			dd = itr2.next();
//			String url = dd.getURL();
//			itr1 = googleScoredOutput.keySet().iterator();
//			GoogleDocument gd;
//			while (itr1.hasNext()) {
//				gd = itr1.next();
//				if (!(gd.getURL().equals(url))) {
//					finalOutput.put(gd, impFac * documentRanks.get(dd));
//				}
//			}
//		}
//		return finalOutput;
//	}
//}
